package collage;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

public class ImagePanel extends JPanel {

    private BufferedImage img = null;
    private BufferedImage origImg = null;
    Point mouseStart = null, startLoc = null;
    boolean selected = false;
    private int currentAngle;

    public ImagePanel(String filename, int dst_width, int dst_height) throws Exception {
        origImg = ImageIO.read(new File(filename));

        init(dst_width, dst_height);
    }

    public ImagePanel(BufferedImage srcImage, int dst_width, int dst_height) throws Exception {
        origImg = srcImage;
        init(dst_width, dst_height);

    }
    public ImagePanel(BufferedImage srcImage, int dst_width, int dst_height, int angle) throws Exception {
        origImg = srcImage;
        currentAngle = angle;
        init(dst_width, dst_height);
    }
    
    private void init(int dst_width, int dst_height) {
        int src_width = origImg.getWidth(null);
        int src_height = origImg.getHeight(null);
        float ratio = Math.max(src_width / (float) dst_width,
                src_height / (float) dst_height);
        dst_width = Math.round(src_width / ratio);
        dst_height = Math.round(src_height / ratio);

        Dimension size = new Dimension(dst_width, dst_height);
        setPreferredSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
        setSize(size);        
        setLayout(null);

        updateImage();       
        
        //add context menu
        //setComponentPopupMenu(contextMenu);
        //TODO: add context menu should have been here
    }
    
    public void quickUpdate() {
        img = getScaledInstance(img, getWidth(), getHeight(), 
                RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR, false);
    }
    
    public void updateImage() {
        img = getScaledInstance(origImg, getWidth(), getHeight(), 
                RenderingHints.VALUE_INTERPOLATION_BICUBIC, false);
    }
    
    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(img, 0, 0, null);
        if (selected) {

            if(currentAngle !=0){
            AffineTransform origXform = g2.getTransform();
            AffineTransform newXform = (AffineTransform)(origXform.clone());
            //center of rotation is center of the panel
            int xRot = this.getWidth()/2;
            int yRot = this.getHeight()/2;
            newXform.rotate(Math.toRadians(currentAngle), xRot, yRot);
            g2.setTransform(newXform);
            //draw image centered in panel
            int x = (getWidth() - img.getWidth(this))/2;
            int y = (getHeight() - img.getHeight(this))/2;
            g2.drawImage(img, x, y, this);
            g2.setTransform(origXform);
            }

            g2.setStroke(new BasicStroke(1));
            g2.setColor(Color.WHITE);
            g2.drawRect(0, 0, this.getWidth() - 1, this.getHeight() - 1);
            g2.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
                    BasicStroke.JOIN_MITER, 10, new float[]{6}, 0));
            g2.setColor(Color.BLACK);
            g2.drawRect(0, 0, this.getWidth() - 1, this.getHeight() - 1);


        }
    }

    public BufferedImage getScaledInstance(BufferedImage img,
            int targetWidth,
            int targetHeight,
            Object hint,
            boolean higherQuality) {
        int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage ret = (BufferedImage) img;
        int w,   h;
        if (higherQuality) {
            // Use multi-step technique: start with original size, then
            // scale down in multiple passes with drawImage()
            // until the target size is reached
            w = img.getWidth();
            h = img.getHeight();
        } else {
            // Use one-step technique: scale directly from original
            // size to target size with a single drawImage() call
            w = targetWidth;
            h = targetHeight;
        }

        do {
            if (higherQuality && w > targetWidth) {
                w /= 2;
                if (w < targetWidth) {
                    w = targetWidth;
                }
            }

            if (higherQuality && h > targetHeight) {
                h /= 2;
                if (h < targetHeight) {
                    h = targetHeight;
                }
            }

            BufferedImage tmp = new BufferedImage(w, h, type);
            Graphics2D g2 = tmp.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(ret, 0, 0, w, h, null);
            g2.dispose();

            ret = tmp;
        } while (w != targetWidth || h != targetHeight);

        return ret;
    }

    public void alert(String msg) {
        JOptionPane.showMessageDialog(null, msg);
    }
    
    public BufferedImage getImage() {
        return img;
    }
    
    public BufferedImage getOrigImage() {
        return origImg;
    }
    
    public void setImage(BufferedImage newImage) {
        img = newImage;
        
    }

    public void setOrigImage(BufferedImage newImage) {
        origImg = newImage;
        
    }
    
    public void fitImage() {
        setSize(img.getWidth(), img.getHeight());        
        
    }
    public void setAngle(int angle){currentAngle = angle;}
    
    
}